



import bpy
from bpy.types import Operator
from 全局控制.Node.节点和插座基类.bl_UpdateNode import *
import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
import 全局控制.Node.插座.bl_插座基类 as 插件基类
from 全局控制.Node.节点数据类型 import bl_集合数据类型



E_类型枚举 = [
	("TYPE_加法", "+", "", 0),
	("TYPE_减法", "-", "", 1),
	("TYPE_乘法", "*", "", 2),
	("TYPE_除法", "/", "", 3),
	("TYPE_取余", "%", "", 4),

	("TYPE_取反", "！", "", 5),
	("TYPE_左移", "<<", "", 6),
	("TYPE_右移", ">>", "", 7),

	("TYPE_按位与", "&", "&", 8),
	("TYPE_按位或", "|", "|", 9),
	("TYPE_按异或", "^", "^", 10),
]






class C_SceneNode_逆向(基类.C_SN_基类):
	bl_dname = 'bl_node_逆向'
	bl_label = '逆向'
	
	#m_物体name前缀 = bpy.props.StringProperty(name='前缀')
	def init(self, context):
		super(C_SceneNode_逆向, self).f_init(context)
		self.inputs.new('C_NodeSocket_引用', name='<-')
		self.outputs.new('C_NodeSocket_引用', name='<-')
		self.m_Type = '逆向'

	def draw_buttons(self, context, layout):
		#layout.prop(self, 'm_运算类型')
		pass

	def f_update(self, 是否向下传递=False, input插座=None):
		data = self.inputs['<-'].f_setData()
		self.outputs['<-'].f_setData(data)
		super(C_SceneNode_逆向, self).f_update(是否向下传递, input插座)
		


class C_NODE_AddMenu_逆向(bpy.types.Operator):
	bl_idname = 'node.global_node_reverse'
	bl_label = '逆向节点'
	bl_options = {'REGISTER', 'UNDO'}
	
	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_SceneNode_逆向', use_transform=True)
		return {'FINISHED'}




import pdb










def f_update(self, context):
	print('引用节点名称 = ', self)
class C_引用节点名称(bpy.types.PropertyGroup):	
	value = bpy.props.StringProperty(update=f_update)

class C_ops_清除链接到的实例节点(bpy.types.Operator):
	bl_idname = 'node.update_node_clear_linknode'
	bl_label = '清除链接到的实例节点'
	bl_options = {'REGISTER', 'UNDO'}

	m_节点层 = bpy.props.StringProperty(name='节点层')
	m_节点名 = bpy.props.StringProperty(name='节点名')
	
	def execute(self, context):
		nodeGroup = bpy.data.node_groups[self.m_节点层]
		node = nodeGroup.nodes[self.m_节点名]

		for item in node.m_连接引用节点列表:
			ID = node.id_data.nodes.find(item.value)
			if ID >= 0 :
				n = node.id_data.nodes[ID]
				node.id_data.nodes.remove(n)
		node.m_连接引用节点列表.clear()
		return {'FINISHED'}


class C_SceneNode_引用(基类.C_SN_基类):
	bl_dname = 'bl_node_引用'
	bl_label = '引用'
	
	m_连接引用节点列表 = bpy.props.CollectionProperty(type=C_引用节点名称)
	m_引用节点名称 = bpy.props.StringProperty(name='引用的节点名称')
	m_开启定点更新 = bpy.props.BoolProperty(name='定点更新', default=False)
	def init(self, context):
		super(C_SceneNode_引用, self).f_init(context)
		self.inputs.new('C_NodeSocket_引用', name='=>')
		self.outputs.new('C_NodeSocket_引用', name='=>')
		self.m_Type = '引用'
		self.outputs[0].hide = True
		#运行节点隐藏
		#self.inputs[0].hide = True

	def draw_buttons_ext(self, context, layout):
		if self.m_引用节点名称 != '':
			layout.prop(self, 'm_引用节点名称')
			
	def draw_buttons(self, context, layout):
		#layout.prop(self, 'm_开启定点更新')
		if self.m_引用节点名称 == '' :
			ops = layout.operator('node.update_node_clear_linknode', text='清除连接实例')
			ops.m_节点层 = self.id_data.name
			ops.m_节点名 = self.name
	
	def draw_label(self):
		return '引用的节点:' + self.m_引用节点名称
	def update(self):
		if self.m_引用节点名称 == "" and self.inputs[1].is_linked:
			outSocket = f_get上一层Output插座(self.inputs[1])
			if outSocket :
				self.inputs[1].f_setData(outSocket.f_getData())

	def f_is强制Update(self):
		return True


	def f_update(self, 是否向下传递=False, input插座=None):
		
		if self.m_引用节点名称 != "" :
			#被引用的节点 = self.id_data.nodes[name.value]
			#f_递归到子节点Update(self.outputs)

			连接到的节点 = f_get子节点and输入插座(self.outputs)
			#print('连接到的节点 引用的节点 = ', 连接到的节点, self.outputs[0].f_getData())
			for ns in 连接到的节点:
				#print('引用的节点 = ', ns, ns[1])
				ns[0].f_input插座Update(ns[1], self.outputs[0])
				ns[0].f_update(False, ns[1])
				pass
				
		else:
			#if 是否向下传递 == False :
			#print('self.m_引用节点名称 = ', len(self.m_引用节点名称), self.m_引用节点名称, self.name, self.m_连接引用节点列表)
			上一层outSocket = f_get上一层Output插座(self.inputs['=>'])
			if 上一层outSocket :
				self.inputs[1].f_setData(上一层outSocket.f_getData())
			else:
				return

			#for i in self.m_连接引用节点列表 : print('self.m_连接引用节点列表 = ', self.name, i.value)
			for name in self.m_连接引用节点列表:
				输入数据 = self.inputs['=>'].f_getData()
				ID = self.id_data.nodes.find(name.value)
				#print('引用 name = ', ID, name.value)
				if ID >= 0 :
					被引用的节点 = self.id_data.nodes[ID]
					#print('被引用的节点 = ', 被引用的节点, 输入数据)
					被引用的节点.outputs[0].f_setData( 输入数据 )
					被引用的节点.f_update()
					
					print('引用节点 调用被引用节点错误！\n\b 没有找到被引用节点,肯节点不存在或已删除.')
		#super(C_SceneNode_引用, self).f_update(是否向下传递, input插座)
		

	def copy(self, node):
		#print('拷贝 = ', node)
		item = node.m_连接引用节点列表.add()
		item.value = self.name
		print('copy = ', node, item, item.value)
		self.m_引用节点名称 = node.name
		
		self.inputs[1].hide = True
		self.outputs[0].hide = False

		self.use_custom_color = True
		self.color = (0.1, 0.2, 0.1)
		self.m_Type = '引用镜像'
		
		#print('copy = ', self.name, node.name)
		

class C_NODE_AddMenu_引用(bpy.types.Operator):
	bl_idname = 'node.global_node_reference'
	bl_label = '引用节点'
	bl_options = {'REGISTER', 'UNDO'}
	
	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_SceneNode_引用', use_transform=True)
		return {'FINISHED'}


classes = (
	C_SceneNode_逆向,
	C_NODE_AddMenu_逆向,
	
	C_ops_清除链接到的实例节点,
	C_引用节点名称,
	C_SceneNode_引用,
	C_NODE_AddMenu_引用,

)




def register():
	for c in classes:
		bpy.utils.register_class(c)
		

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)

	

